<?php

namespace App\Services;



use EasyWeChat\Factory;
use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
use EasyWeChat\Kernel\Support\Collection;
use EasyWeChat\Payment\Application;
use Exception;
use Psr\Http\Message\ResponseInterface;
use Symfony\Component\HttpFoundation\Response;

class WechatService
{
    private $apiLinkService;
    private $logger;

    public function __construct(ApiLinkService $apiLinkService)
    {
        $this->apiLinkService = $apiLinkService;
        $this->logger = customerLoggerHandle('WechatService');
    }

    /**
     * 获取微信用户信息，如：openid， session_key
     * @param $jsCode
     * @param $appId
     * @param $secret
     * @return mixed
     * @throws InvalidConfigException
     */
    public function getOpenIdForCode($jsCode, $appId, $secret)
    {
//        $miniProgramConfig = [
//            'app_id' => env('WECHAT_MINI_PROGRAM_APP_ID'),
//            'secret' => env('WECHAT_MINI_PROGRAM_SECRET'),
//        ];
        $miniProgramConfig = [
            'app_id' => $appId,
            'secret' => $secret,
        ];

        $miniProgram = Factory::miniProgram($miniProgramConfig);
        return $miniProgram->auth->session($jsCode);
    }

    /**
     * 消息解码
     * @param $appId
     * @param $secret
     * @param $encryptedData
     * @param $iv
     * @param $session
     * @return array
     * @throws \EasyWeChat\Kernel\Exceptions\DecryptException
     */
    public function miniProgramEncryptor($appId, $secret, $encryptedData, $iv, $session)
    {
        $miniProgramConfig = [
            'app_id' => $appId,
            'secret' => $secret,
        ];

        $miniProgram = Factory::miniProgram($miniProgramConfig);

        return $miniProgram->encryptor->decryptData($session, $iv, $encryptedData);
    }

    /**
     * 实例化微信支付模组
     * @param array $extraConfig
     * @return Application
     */
    private function getWechatPayment($extraConfig = []): Application
    {
        $paymentConfig = [
            // 必要配置
            'app_id'    => env('WECHAT_APP_ID'),
            'mch_id'    => env('WECHAT_PAYMENT_MERCHANT_ID'),//商户号
            'key'       => env('WECHAT_PAYMENT_KEY'),   // API 密钥
            'sub_appid' => env('WECHAT_MINI_PROGRAM_APP_ID'),//小程序appid
            // 如需使用敏感接口（如退款、发送红包等）需要配置 API 证书路径(登录商户平台下载 API 证书)
            'cert_path' => env('WECHAT_PAYMENT_CERT_PATH'), // XXX: 绝对路径！！！！
            'key_path'  => env('WECHAT_PAYMENT_KEY_PATH'),      // XXX: 绝对路径！！！！
        ];
        $paymentConfig = array_merge($paymentConfig, $extraConfig);
        $wechatPayment = Factory::payment($paymentConfig);

        return $wechatPayment;
    }

    /**
     * 获取商户小程序二维码
     * @param $merchantCode
     * @return array|Collection|object|ResponseInterface|string
     */
    public
    function merchantQRCode($merchantCode)
    {
        $miniProgramConfig = [
            'app_id' => env('WECHAT_MINI_PROGRAM_APP_ID'),
            'secret' => env('WECHAT_MINI_PROGRAM_SECRET'),
        ];
        $miniProgramApp = Factory::miniProgram($miniProgramConfig);
        return $miniProgramApp->app_code->getUnlimit("merchantCode=$merchantCode", [
            'page'  => 'pages/cashBar/cashBar',
            'width' => 600,
        ]);
    }

    /**
     * 创建微信订单
     * @param $order
     * @return mixed
     * @throws Exception
     */
//    public function wxCreateOrder(Order $order)
//    {
//        $wechatPayment = $this->getWechatPayment();
//
//        try {
//
//            if (!empty($order->wechat_order_no)) {
//                $payData = $wechatPayment->jssdk->bridgeConfig($order->wechat_order_no, false);
//            } else {
//                //组织构建统一下单的参数
//                $attributes = $this->getUnifyOrderAttributes($order);
//
//                $this->logger->debug("订单创建信息", $attributes);
//                $result = $wechatPayment->order->unify($attributes);
//                $this->logger->debug("订单创建返回", [$result]);
//
//                if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
//                    $prepayId = $result['prepay_id'];
//                    $order->wechat_order_no = $prepayId;
//                    $order->save();//保存微信统一下单返回的数据
//
//                    $payData = $wechatPayment->jssdk->bridgeConfig($prepayId, false);
//                } else {
//                    throw new Exception("微信下单失败");
//                }
//            }
//
//            return $payData;
//
//        } catch (Exception $exception) {
//            $this->logger->debug('异常!', getExceptionInfo($exception));
//            throw new ServiceException(null, '系统繁忙!微信下单失败');
//        }
//    }

    /**
     * 微信支付通知
     * @param $request
     * @return Response
     * @throws \EasyWeChat\Kernel\Exceptions\Exception
     */
//    public function notify($request)
//    {
//        $wechatPayment = $this->getWechatPayment();
//        $wechatPayment['request'] = $request;
//        $this->logger->debug("收到推送通知", [$wechatPayment['request']]);
//        $response = $wechatPayment->handlePaidNotify(function ($message, $fail) {
//            // 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单
//            $this->logger->debug("当前订单信息", $message);
//            /** @var Order $order */
//            $order = Order::whereOrderNo($message['out_trade_no'])->first();
//            $this->logger->debug("当前订单信息", [
//                'orderNo'     => $order->order_no,
//                'orderStatus' => BaseConstants::ORDER_STATUS_MAP[$order->order_status]
//            ]);
//
//            if (!$order) { // 如果订单不存在
//                $this->logger->debug("订单未找到!");
//                return 'Order not exist.'; // 告诉微信，我已经处理完了，订单没找到，别再通知我了
//            }
//
//            // 如果订单存在
//            // 检查订单是否已经更新过支付状态
//            if ($order->order_status != BaseConstants::ORDER_STATUS_INIT) { // 假设订单字段“支付时间”不为空代表已经支付
//                $this->logger->debug("已经支付成功了就不再更新!");
//                return true; // 已经支付成功了就不再更新了
//            }
//
//            if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态，不代表支付状态
//                // 用户是否支付成功
//                if (array_get($message, 'result_code') === 'SUCCESS') {
//
//                    $order->order_status = BaseConstants::ORDER_STATUS_PAY;
//                    $order->wechat_transaction_id = $message['transaction_id'];
//                    $order->pay_time = date('Y-m-d H:i:s');
//                    $order->wechat_pay_info = json_encode($message);
//                    $order->save(); // 保存订单
//
//                    dispatch(new OrderConfirmJob($order->order_no));
//
//                    $this->logger->debug("订单支付成功", [$order->order_no]);
//
//                    // 用户支付失败
//                } elseif (array_get($message, 'result_code') === 'FAIL') {
//                    $this->logger->debug("用户支付失败");
//                }
//
//            } else {
//                return $fail('通信失败，请稍后再通知我');
//            }
//
//
//            $this->logger->debug("变更订单信息", [
//                'orderNo'     => $order->order_no,
//                'orderStatus' => BaseConstants::ORDER_STATUS_MAP[$order->order_status]
//            ]);
//
//            return true; // 返回处理完成
//        });
//
//        return $response;
//    }

    /**
     * 微信支付退款
     * @param $subMchId
     * @param $transactionId
     * @param $orderNo
     * @param $totalFee
     * @param $refundFee
     * @param string $refundDesc
     * @return array|Collection|object|ResponseInterface|string
     * @throws Exception
     */
    public function wxRefundOrderQueue($subMchId, $transactionId, $orderNo, $totalFee, $refundFee, $refundDesc = '订单退款')
    {
        try {
            $extraConfig = [
                'sub_mch_id' => $subMchId
            ];
            $wechatPayment = $this->getWechatPayment($extraConfig);

            //微信退款
            $wxRefund = $wechatPayment->refund->byTransactionId($transactionId, $orderNo, $totalFee, $refundFee,
                ['refund_desc' => $refundDesc]);
            return $wxRefund;
        } catch (Exception $exception) {
            $this->logger->debug('退款异常!', getExceptionInfo($exception));
            throw  $exception;
        }

    }

    /**
     * 拼装创建微信订单字段
     * @param Order $order
     * @return array
     */
//    private function getUnifyOrderAttributes(Order $order): array
//    {
//        /**
//         * 场景信息
//         * {
//         *  "store_info":{
//         *      "id":"SZTX001",
//         *      "name":"腾大餐厅",
//         *      "area_code":"440305",
//         *      "address":"科技园中一路腾讯大厦"
//         *  }
//         * }
//         */
//        $sceneInfo = [
//            'id'        => $order->merchantDetail->merchant_no,
//            'name'      => $order->merchantDetail->name,
//            'area_code' => $order->merchantDetail->area_code,
//            'address'   => $order->merchantDetail->address,
//        ];
//        $attributes = [
//            'trade_type'     => 'JSAPI', // JSAPI，NATIVE，APP...
//            'sub_mch_id'     => $order->merchantDetail->sub_mch_id,
//            'scene_info'     => json_encode($sceneInfo),
//            'body'           => $order->title,
//            'detail'         => $order->title,
//            'out_trade_no'   => $order->order_no,
//            'total_fee'      => $order->pay_price, // 单位：分
//            'time_expire'    => date('YmdHis', strtotime($order->lose_time)),
//            'notify_url'     => url(env('WECHAT_NOTIFY_URL')), // 支付结果通知网址，如果不设置则会使用配置里的默认地址
//            'sub_openid'     => $order->appUser->open_id, // trade_type=JSAPI，此参数必传，用户在商户appid下的唯一标识，
//            'profit_sharing' => 'Y'//分账参数
//            //'openid'   => $order->appUser->open_id, //服务商模式不传openid
//        ];
//
//        return $attributes;
//    }


}
